package dynamic.mybatisplus.core.conditions.query;

import com.baomidou.mybatisplus.core.conditions.ISqlSegment;
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.conditions.segments.NormalSegmentList;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import dynamic.DynamicEntity;
import dynamic.metadata.DTableFieldInfo;
import dynamic.metadata.DTableInfo;
import dynamic.metadata.DTableInfoHelper;
import java.util.Objects;



public abstract class DWrapper implements ISqlSegment {
    public DWrapper() {
    }

    public abstract DynamicEntity getEntity();

    public String getSqlSelect() {
        return null;
    }

    public String getSqlSet() {
        return null;
    }

    public String getSqlComment() {
        return null;
    }

    public String getSqlFirst() {
        return null;
    }

    public abstract MergeSegments getExpression();

    public String getCustomSqlSegment() {
        MergeSegments expression = this.getExpression();
        if (Objects.nonNull(expression)) {
            NormalSegmentList normal = expression.getNormal();
            String sqlSegment = this.getSqlSegment();
            if (StringUtils.isNotBlank(sqlSegment)) {
                if (normal.isEmpty()) {
                    return sqlSegment;
                }

                return "WHERE " + sqlSegment;
            }
        }

        return "";
    }

    public boolean isEmptyOfWhere() {
        return this.isEmptyOfNormal() && this.isEmptyOfEntity();
    }

    public boolean isNonEmptyOfWhere() {
        return !this.isEmptyOfWhere();
    }

    /** @deprecated */
    @Deprecated
    public boolean nonEmptyOfWhere() {
        return this.isNonEmptyOfWhere();
    }

    public boolean isEmptyOfNormal() {
        return CollectionUtils.isEmpty(this.getExpression().getNormal());
    }

    public boolean isNonEmptyOfNormal() {
        return !this.isEmptyOfNormal();
    }

    /** @deprecated */
    @Deprecated
    public boolean nonEmptyOfNormal() {
        return this.isNonEmptyOfNormal();
    }

    public boolean isNonEmptyOfEntity() {
        DynamicEntity entity = this.getEntity();
        if (entity == null) {
            return false;
        } else {
            DTableInfo tableInfo = DTableInfoHelper.getTableInfo(entity.getEntityClass());
            if (tableInfo == null) {
                return false;
            } else if (tableInfo.getFieldList().stream().anyMatch((e) -> {
                return this.fieldStrategyMatch(tableInfo, entity, e);
            })) {
                return true;
            } else {
                return StringUtils.isNotBlank(tableInfo.getKeyProperty()) && Objects.nonNull(tableInfo.getPropertyValue(entity, tableInfo.getKeyProperty()));
            }
        }
    }

    /** @deprecated */
    @Deprecated
    public boolean nonEmptyOfEntity() {
        return this.isNonEmptyOfEntity();
    }

    private boolean fieldStrategyMatch(DTableInfo tableInfo, DynamicEntity entity, DTableFieldInfo e) {
        switch(e.getWhereStrategy()) {
            case IGNORED:
            case ALWAYS:
                return true;
            case NOT_EMPTY:
                return StringUtils.checkValNotNull(tableInfo.getPropertyValue(entity, e.getProperty()));
            case NEVER:
                return false;
            case NOT_NULL:
            default:
                return Objects.nonNull(tableInfo.getPropertyValue(entity, e.getProperty()));
        }
    }

    public boolean isEmptyOfEntity() {
        return !this.isNonEmptyOfEntity();
    }

    public String getTargetSql() {
        return this.getSqlSegment().replaceAll("#\\{.+?}", "?");
    }

    public abstract void clear();
}
